package com.tanhua.server.interceptor;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tanhua.utils.Cache;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@Component
public class RedisCacheInterceptor implements HandlerInterceptor {

    @Value("${tanhua.cache.enable}")
    private Boolean cacheEnable;

    public static final ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        /**
         * 返回true表示放行
         */

        //判断是否开启了缓存功能
        if (!cacheEnable){
            return true;
        }

        //判断是否拦截的是方法
        if (!(handler instanceof HandlerMethod)){
            return true;
        }

        //如果拦截的是方法, 判断该拦截器是不是拦截的get请求
        if(!((HandlerMethod) handler).hasMethodAnnotation(GetMapping.class)){
            return true;
        }

        //如果是get请求, 是否添加了我们自定义的cache注解
        if(!((HandlerMethod) handler).hasMethodAnnotation(Cache.class)){
            return true;
        }

        //如果添加了cache注解, 判断请求的数据是否在缓存中已经存在
        //先设置查询Redis缓存的key
        String redisKey = getRedisKey(request);
        String cacheData =  (String) redisTemplate.opsForValue().get(redisKey);
        if (StringUtils.isEmpty(cacheData)){
            //缓存未命中,放行
            return true;
        }

        //缓存命中的话, 将缓存中的数据返回给前端, 设置返回值类型为json类型, 编码格式为utf-8
        response.setContentType("text/html;charset=utf-8");
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(cacheData);

        return true;
    }

    //设置缓存的key, 查询缓存的key由请求url, token, 和请求参数三者进行MD5加密之后组成
    public String getRedisKey(HttpServletRequest request) throws JsonProcessingException {
        String requestURI = request.getRequestURI();
        Map<String, String[]> parameterMap = request.getParameterMap();
        String requestparam = objectMapper.writeValueAsString(parameterMap);
        String token = request.getHeader("Authorization");
        String key = requestURI+"_"+requestparam+"_"+token;
        return DigestUtils.md5Hex(key);

    }

}
